#include "matclassbas.h"
matrix::matrix(mat_t m, mat_t n, mat_t *data) : m(m), n(n)
{
    mat.resize(m);
    if (data == nullptr)
    {
        // 空矩阵处理
        for (mat_t i = 0; i < m; i++)
            mat[i].resize(n, 0);
        return;
    }
    for (mat_t i = 0; i < m; i++)
    {
        mat[i].resize(n);
        for (mat_t j = 0; j < n; j++)
        {
            mat[i][j] = data[i * n + j];
        }
    }
}
matrix::matrix(mat_t m, mat_t n, mat_t val) : m(m), n(n)
{
    mat.resize(m);
    if (data == nullptr)
    {
        // 空矩阵处理
        for (mat_t i = 0; i < m; i++)
            mat[i].resize(n, 0);
        return;
    }
    for (mat_t i = 0; i < m; i++)
    {
        mat[i].resize(n);
        for (mat_t j = 0; j < n; j++)
        {
            mat[i][j] = val;
        }
    }
}
mat_t matrix::getm() const
{
    return this->m;
}
mat_t matrix::getn() const
{
    return this->n;
}
std::vector<mat_t> matrix::getval(mat_t x,mat_t y) const 
{
    x--;
    y--;
    std::vector<mat_t> ans;
    if(x<0||y<0||x>=this->m||y>=this->n)
    {
        return ans;
    }
    if(y==0)
        return this->mat[x];
    if(x==0)
    {
        for (int i = 0; i < this->m;i++)
        {
            ans.push_back(this->mat[i][y]);
        }
        return ans;
    }
    ans.push_back(mat[x][y]);
    return ans;
}
bool matrix::operator^=(const matrix &b) const
{
    mat_t m = b.getm(), n = b.getn();
    if (this->m != m || this->n != n)
        return false;
    else
        return true;
}
bool matrix::operator==(const matrix& b) const
{
    if(!((*this)^=b)) return false;
    for (int i = 0; i < m;i++)
    {
        for (int j = 0; j < n;j++)
        {
            std::vector<mat_t> temp = b.getval(i, j);
            if (this->mat[i][j] != temp[0])
                return false;
        }
    }
    return true;
}
bool matrix::operator!=(const matrix& b)const 
{
    return !((*this) == b);
}
// 初等行变换：第x行乘以a
void matrix::change_r_muti(mat_t x, double a)
{
    if (x < 1 || x > m)
        return; // 非法行号
    for (mat_t j = 0; j < n; j++)
    {
        mat[x - 1][j] *= a;
    }
}

// 初等行变换：交换第x行和第y行
void matrix::change_r_change(mat_t x, mat_t y)
{
    if (x < 1 || x > m || y < 1 || y > m || x == y)
        return; // 非法行号或相同行
    std::swap(mat[x - 1], mat[y - 1]);
}

// 初等行变换：将第y行加到第x行
void matrix::change_r_add(mat_t x, mat_t y)
{
    if (x < 1 || x > m || y < 1 || y > m || x == y)
        return; // 非法行号或相同行
    for (mat_t j = 0; j < n; j++)
    {
        mat[x - 1][j] += mat[y - 1][j];
    }
}

// 初等列变换：第x列乘以a
void matrix::change_c_muti(mat_t x, double a)
{
    if (x < 1 || x > n)
        return; // 非法列号
    for (mat_t i = 0; i < m; i++)
    {
        mat[i][x - 1] *= a;
    }
}

// 初等列变换：交换第x列和第y列
void matrix::change_c_change(mat_t x, mat_t y)
{
    if (x < 1 || x > n || y < 1 || y > n || x == y)
        return; // 非法列号或相同列
    for (mat_t i = 0; i < m; i++)
    {
        std::swap(mat[i][x - 1], mat[i][y - 1]);
    }
}

// 初等列变换：将第y列加到第x列
void matrix::change_c_add(mat_t x, mat_t y)
{
    if (x < 1 || x > n || y < 1 || y > n || x == y)
        return; // 非法列号或相同列
    for (mat_t i = 0; i < m; i++)
    {
        mat[i][x - 1] += mat[i][y - 1];
    }
}
// 矩阵加法
matrix matrix::operator+(const matrix &b)const
{
    if (!(*this ^= b))
        return mat_error;
    matrix result(m, n, nullptr); 
    for (mat_t i = 0; i < m; i++)
    {
        for (mat_t j = 0; j < n; j++)
        {
            result.mat[i][j] = mat[i][j] + b.mat[i][j];
        }
    }
    return result;
}
// 矩阵数乘
matrix matrix::operator*(mat_t b)const 
{
    matrix result(m, n, nullptr);
    for (mat_t i = 0; i < m; i++)
    {
        for (mat_t j = 0; j < n; j++)
        {
            result.mat[i][j] = mat[i][j] * b;
        }
    }
    return result;
}

// 友元数乘（实现交换律）
matrix operator*(mat_t b,const matrix &a)
{
    return a * b;
}

// 矩阵求负
matrix matrix::operator-() const
{
    return *this * (-1);
}

// 矩阵减法
matrix matrix::operator-(const matrix &b)const
{
    return *this + (-b);
}
bool matrix::modify(mat_t x,mat_t y,mat_t val)
{
    //检测非法行列号
    if (x < 1 || x > m || y < 1 || y > n )
        return 0;
    this->mat[x-1][y-1] = val;
    return 1;
}
matrix& matrix::operator+=(const matrix &b)
{
    if(!((*this)^=b))
        return mat_error;
    (*this) = (*this) + b;
    return (*this);
}
matrix& matrix::operator-=(const matrix& b)
{
    if (!((*this) ^= b))
        return mat_error;
    (*this)=(*this)-b;
    return (*this);
}
matrix &matrix::operator*=(mat_t b)
{
    (*this) = (*this) * b;
    return (*this);
}
void matrix::resize(mat_t new_rows, mat_t new_cols)
{
    // 创建新矩阵，初始化为零
    std::vector<std::vector<mat_t>> new_mat(new_rows, std::vector<mat_t>(new_cols, 0));

    // 计算需要复制的行数和列数
    mat_t rows_to_copy = std::min(m, new_rows);
    mat_t cols_to_copy = std::min(n, new_cols);

    // 复制原有数据到左上角
    for (mat_t i = 0; i < rows_to_copy; i++)
    {
        for (mat_t j = 0; j < cols_to_copy; j++)
        {
            new_mat[i][j] = mat[i][j];
        }
    }
    // 更新矩阵数据
    mat = std::move(new_mat); // 使用移动语义提高效率
    m = new_rows;
    n = new_cols;
}
void square::transpose()
{
    square transposed(n, m); // 创建转置矩阵
    for (mat_t i = 0; i < m; i++)
    {
        for (mat_t j = 0; j < n; j++)
        {
            transposed(j, i) = mat[i][j];
        }
    }
    // 更新当前矩阵为转置矩阵
    *this = transposed;
    return;
}
mat_t square::getval()
{
    countval();
    return this->val;
}
mat_t square::getr()
{
    countr();
    return this->r;
}
void square::countval()
{
    const mat_t size = m; // 方阵大小
    // 特殊情况处理
    if (size == 0)
    {
        val = 1.0; // 0x0矩阵的行列式定义为1
        return;
    }

    if (size == 1)
    {
        val = static_cast<long double>(mat[0][0]);
        return;
    }
    // 使用高斯消元法计算行列式
    // 创建矩阵的副本以避免修改原始数据
    std::vector<std::vector<long double>> temp(size, std::vector<long double>(size));
    for (mat_t i = 0; i < size; i++)
    {
        for (mat_t j = 0; j < size; j++)
        {
            temp[i][j] = static_cast<long double>(mat[i][j]);
        }
    }
    long double det = 1.0;
    int sign = 1; // 用于跟踪行交换的次数
    // 高斯消元主循环
    for (mat_t col = 0; col < size; col++)
    {
        // 寻找主元（当前列中绝对值最大的元素）
        mat_t max_row = col;
        long double max_val = std::abs(temp[col][col]);
        for (mat_t row = col + 1; row < size; row++)
        {
            if (std::abs(temp[row][col]) > max_val)
            {
                max_val = std::abs(temp[row][col]);
                max_row = row;
            }
        }
        // 如果最大值为0，则行列式为0
        if (max_val < std::numeric_limits<long double>::epsilon())
        {
            val = 0.0;
            return;
        }
        // 如果需要，交换行
        if (max_row != col)
        {
            std::swap(temp[col], temp[max_row]);
            sign = -sign; // 行交换改变行列式符号
        }
        // 消元
        for (mat_t row = col + 1; row < size; row++)
        {
            long double factor = temp[row][col] / temp[col][col];
            for (mat_t j = col; j < size; j++)
            {
                temp[row][j] -= factor * temp[col][j];
            }
        }
        // 累积主对角线元素的乘积
        det *= temp[col][col];
    }
    val = det * sign;
}
void square::countr()
{
    const mat_t size = m; // 方阵大小

    // 特殊情况处理
    if (size == 0)
    {
        R = 0;
        return;
    }

    // 创建矩阵的副本以避免修改原始数据
    std::vector<std::vector<long double>> temp(size, std::vector<long double>(size));
    for (mat_t i = 0; i < size; i++)
    {
        for (mat_t j = 0; j < size; j++)
        {
            temp[i][j] = static_cast<long double>(mat[i][j]);
        }
    }

    mat_t rank = size; // 初始假设满秩

    // 高斯消元主循环
    for (mat_t row = 0; row < size; row++)
    {
        // 寻找主元（当前列中绝对值最大的元素）
        mat_t pivot = row;
        long double max_val = std::abs(temp[row][row]);

        for (mat_t i = row + 1; i < size; i++)
        {
            if (std::abs(temp[i][row]) > max_val)
            {
                max_val = std::abs(temp[i][row]);
                pivot = i;
            }
        }

        // 如果主元接近于0，则秩减少
        if (max_val < std::numeric_limits<long double>::epsilon())
        {
            rank--;
            continue; // 跳过这一列
        }

        // 如果需要，交换行
        if (pivot != row)
        {
            std::swap(temp[row], temp[pivot]);
        }

        // 消元
        for (mat_t i = row + 1; i < size; i++)
        {
            long double factor = temp[i][row] / temp[row][row];
            for (mat_t j = row; j < size; j++)
            {
                temp[i][j] -= factor * temp[row][j];
            }
        }
    }
    R = rank;
}
bool square::operatof==(mat_t x)
{
    getval();
    if(this->val==x)
        return true;
    else
        return false;
}
bool square::operator!=(mat_t x)
{
    return !((*this) == x);
}